<template>
  <div id="component_canvas">
    <canvas id="canvas5"></canvas>
  </div>
</template>

<script>
/* eslint-disable no-prototype-builtins */
/* eslint-disable no-undef */
/* eslint-disable no-empty */
export default {
  name: 'canvas_5',
  data() {
    return {};
  },
  // 过滤器
  filter: {},

  // 计算属性
  computed: {},

  // 监听属性
  watch: {},

  // 组件创建属性绑定，DOM未生成
  created() {},

  // 模板编译挂载之后
  mounted() {
    let c = document.getElementById('canvas5');
    var w = (c.width = window.innerWidth),
      h = (c.height = window.innerHeight),
      ctx = c.getContext('2d'),
      opts = {
        baseBaseSize: 15,
        addedBaseSize: 5,
        baseVel: 2,
        addedVel: 1,
        baseTime: 60,
        addedTime: 20,
        overTime: 5,
        sliding: 0.99,
        particleChance: 0.9,
        particles: 100,
        templateParticleColor: 'hsla(hue,80%,40%,alp)',
        repaintAlpha: 'rgba(0,0,0,.1)',
        startColor: 0.2,
        fullColor: 0.5,
        stopColor: 0.6,
        timeToColorChange: 3
      },
      particles = [],
      tick = 0;

    function Particle() {
      this.reset();
    }
    Particle.prototype.reset = function() {
      this.x = Math.pow(Math.random(), 1 / 4);
      this.y = h / 2;
      var color = opts.templateParticleColor.replace(
        'hue',
        this.x * 360 * 2 + tick * opts.timeToColorChange
      );
      this.baseSize =
        ((Math.random() + this.x) / 2) *
        (opts.baseBaseSize + opts.addedBaseSize * Math.random());
      this.gradient = ctx.createRadialGradient(
        0,
        0,
        0,
        0,
        0,
        this.baseSize / 2
      );
      this.gradient.addColorStop(opts.startColor, color.replace('alp', 0));
      this.gradient.addColorStop(opts.fullColor, color.replace('alp', 1));
      this.gradient.addColorStop(opts.stopColor, color.replace('alp', 1));
      this.gradient.addColorStop(1, color.replace('alp', 0));

      this.vx =
        -(1 + Math.random() / 10 - this.x) *
        (opts.baseVel + Math.random() * opts.addedVel);
      this.vy =
        Math.pow(this.x, 4) *
        (opts.baseVel + Math.random() * opts.addedVel) *
        (Math.random() < 0.5 ? -1 : 1);

      this.x *= w / 2;
      if (Math.random() < 0.5) {
        this.x = w - this.x;
        this.vx *= -1;
      }

      this.time = opts.baseTime + opts.addedTime * Math.random();
      this.tick = this.time + opts.overTime;
    };
    Particle.prototype.step = function() {
      var size;
      if (this.tick <= this.time) {
        this.x += this.vx *= opts.sliding;
        this.y += this.vy *= opts.sliding;
        size = Math.pow(this.tick / this.time, 1 / 2);
      } else size = 1 - (this.tick - this.time) / opts.overTime + 0.000001;

      --this.tick;

      ctx.translate(this.x, this.y);
      ctx.scale(size, size);
      ctx.fillStyle = this.gradient;
      ctx.fillRect(
        -this.baseSize / 2,
        -this.baseSize / 2,
        this.baseSize,
        this.baseSize
      );
      ctx.scale(1 / size, 1 / size);
      ctx.translate(-this.x, -this.y);

      if (this.tick <= 0) this.reset();
    };

    function anim() {
      window.requestAnimationFrame(anim);

      ctx.globalCompositeOperation = 'source-over';
      ctx.fillStyle = opts.repaintAlpha;
      ctx.fillRect(0, 0, w, h);

      ctx.globalCompositeOperation = 'lighter';

      ++tick;

      if (
        particles.length < opts.particles &&
        Math.random() < opts.particleChance
      )
        particles.push(new Particle());

      particles.map(function(particle) {
        particle.step();
      });
    }
    ctx.fillStyle = '#222';
    ctx.fillRect(0, 0, w, h);
    anim();

    window.addEventListener('resize', function() {
      w = c.width = window.innerWidth;
      h = c.height = window.innerHeight;

      ctx.fillStyle = '#222';
      ctx.fillRect(0, 0, w, h);
    });
  },

  // 组件更新前
  beforeUpdate() {},

  // 组件更新后
  updated() {},

  // 事件方法
  methods: {}
};
</script>

<style lang="less" scoped>
#component_canvas {
  width: 100%;
  height: 100%;
  #cancas5 {
    width: 100%;
    height: 100%;
    // background-color: #000;
  }
}
</style>
